// ReactFlow画布组件
import React, { useCallback, useRef, useState, useEffect, useMemo } from 'react';
import ReactFlow, {
  addEdge,
  useNodesState,
  useEdgesState,
  Controls,
  Background,
  Handle,
  Position,
} from 'reactflow';
import type { Node, Edge } from 'reactflow';
import 'reactflow/dist/style.css';
import { Card, Button, Space, Modal, Form, Input, InputNumber, Select, message } from 'antd';
import { EditOutlined, DeleteOutlined, CloseOutlined } from '@ant-design/icons';
import type { FlowNode, FlowConnection, FlowData } from '../types';

const { Option } = Select;

// 自定义节点组件
const CustomNode = ({ data, id }: { data: any; id: string }) => {
  const [editing, setEditing] = useState(false);
  const [form] = Form.useForm();

  // 添加默认值以防止 data 为 undefined
  const nodeData = data || { label: id, type: 'unknown', properties: {}, propertiesSchema: [] };

  const handleEdit = () => {
    form.setFieldsValue(nodeData.properties || {});
    setEditing(true);
  };

  const handleSave = (values: any) => {
    nodeData.onUpdate?.(id, values);
    setEditing(false);
    message.success('属性已更新');
  };

  const handleDelete = () => {
    nodeData.onDelete?.(id);
  };

  return (
    <div style={{ 
      padding: '10px', 
      background: '#fff', 
      border: '2px solid #1890ff', 
      borderRadius: '8px',
      minWidth: '150px',
      position: 'relative'
    }}>
      <Handle type="target" position={Position.Top} />
      <div style={{ fontWeight: 'bold', marginBottom: '8px' }}>{nodeData.label || id}</div>
      <div style={{ fontSize: '12px', color: '#666' }}>{nodeData.type || 'unknown'}</div>
      <Space style={{ position: 'absolute', top: '5px', right: '5px' }}>
        <Button 
          type="text" 
          size="small" 
          icon={<EditOutlined />} 
          onClick={handleEdit}
          style={{ padding: '0 4px' }}
        />
        <Button 
          type="text" 
          size="small" 
          danger
          icon={<DeleteOutlined />} 
          onClick={handleDelete}
          style={{ padding: '0 4px' }}
        />
      </Space>
      <Handle type="source" position={Position.Bottom} />
      
      <Modal
        title={`编辑 ${nodeData.label || id} 属性`}
        open={editing}
        onCancel={() => setEditing(false)}
        footer={null}
        width={500}
      >
        <Form
          form={form}
          layout="vertical"
          onFinish={handleSave}
        >
          {nodeData.propertiesSchema?.map((prop: any) => (
            <Form.Item
              key={prop.name}
              name={prop.name}
              label={prop.label}
              rules={prop.required ? [{ required: true, message: `请输入${prop.label}` }] : []}
            >
              {prop.type === 'number' ? (
                <InputNumber style={{ width: '100%' }} {...prop} />
              ) : prop.type === 'select' ? (
                <Select>
                  {prop.options?.map((opt: string) => (
                    <Option key={opt} value={opt}>{opt}</Option>
                  ))}
                </Select>
              ) : (
                <Input {...prop} />
              )}
            </Form.Item>
          ))}
          <Form.Item>
            <Space>
              <Button type="primary" htmlType="submit">保存</Button>
              <Button onClick={() => setEditing(false)}>取消</Button>
            </Space>
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

const nodeTypes = {
  custom: CustomNode,
};

interface FeatureFlowCanvasProps {
  flowData?: FlowData;
  onFlowChange?: (flowData: FlowData) => void;
  onRun?: () => void;
  logs?: string[];
}

// 可用的组件列表
const availableComponents = [
  {
    type: 'input',
    label: '数据输入',
    icon: '📥',
    propertiesSchema: [
      { name: 'dataset', label: '特征集', type: 'text', required: true },
      { name: 'columns', label: '选择列', type: 'text', required: false },
    ]
  },
  {
    type: 'preprocess',
    label: '数据预处理',
    icon: '🔧',
    propertiesSchema: [
      { name: 'method', label: '处理方法', type: 'select', required: true, options: ['标准化', '归一化', '缺失值填充'] },
      { name: 'params', label: '参数', type: 'text', required: false },
    ]
  },
  {
    type: 'operator',
    label: '特征操作',
    icon: '⚙️',
    propertiesSchema: [
      { name: 'operation', label: '操作类型', type: 'select', required: true, options: ['聚合', '转换', '计算'] },
      { name: 'expression', label: '表达式', type: 'text', required: false },
    ]
  },
  {
    type: 'merge',
    label: '数据合并',
    icon: '🔀',
    propertiesSchema: [
      { name: 'mergeType', label: '合并类型', type: 'select', required: true, options: ['内连接', '外连接', '左连接', '右连接'] },
      { name: 'key', label: '关联键', type: 'text', required: true },
    ]
  },
  {
    type: 'output',
    label: '输出',
    icon: '📤',
    propertiesSchema: [
      { name: 'outputName', label: '输出名称', type: 'text', required: true },
      { name: 'format', label: '输出格式', type: 'select', required: true, options: ['CSV', 'JSON', 'Parquet'] },
    ]
  },
];

const FeatureFlowCanvas: React.FC<FeatureFlowCanvasProps> = ({
  flowData,
  onFlowChange,
  onRun,
  logs = []
}) => {
  // 初始化节点，确保每个节点都有正确的 data 结构
  const getInitialNodes = () => {
    if (!flowData?.nodes) return [];
    return flowData.nodes.map(node => ({
      id: node.id,
      type: 'custom',
      position: node.position,
      data: {
        label: node.name || node.id,
        type: node.type || 'unknown',
        properties: node.properties || {},
        propertiesSchema: availableComponents.find(c => c.type === node.type)?.propertiesSchema || [],
        // 回调函数将在 useEffect 中设置
        onUpdate: undefined,
        onDelete: undefined
      }
    }));
  };

  const [nodes, setNodes, onNodesChange] = useNodesState(getInitialNodes());
  const [edges, setEdges, onEdgesChange] = useEdgesState(
    flowData?.connections?.map(conn => ({
      id: conn.id,
      source: conn.source,
      target: conn.target,
      sourceHandle: conn.sourceHandle,
      targetHandle: conn.targetHandle,
    })) || []
  );
  const [selectedComponent, setSelectedComponent] = useState<string | null>(null);
  const reactFlowWrapper = useRef<HTMLDivElement>(null);
  const [reactFlowInstance, setReactFlowInstance] = useState<any>(null);

  // 更新flowData
  useEffect(() => {
    if (flowData) {
      setNodes(flowData.nodes.map(node => ({
        id: node.id,
        type: 'custom',
        position: node.position,
        data: {
          label: node.name || node.id,
          type: node.type || 'unknown',
          properties: node.properties || {},
          onUpdate: handleNodeUpdate,
          onDelete: handleNodeDelete,
          propertiesSchema: availableComponents.find(c => c.type === node.type)?.propertiesSchema || []
        }
      })));
      setEdges(
        flowData.connections?.map(conn => ({
          id: conn.id,
          source: conn.source,
          target: conn.target,
          sourceHandle: conn.sourceHandle,
          targetHandle: conn.targetHandle,
        })) || []
      );
    } else {
      // 如果 flowData 为空，清空节点和边
      setNodes([]);
      setEdges([]);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [flowData]);

  // 使用 useMemo 来避免频繁创建新的 FlowData 对象
  const updatedFlowData = useMemo(() => {
    return {
      nodes: nodes.map(node => ({
        id: node.id,
        type: node.type as any,
        name: node.data?.label || node.id,
        position: node.position,
        properties: node.data?.properties || {}
      })),
      connections: edges.map(edge => ({
        id: edge.id,
        source: edge.source,
        target: edge.target,
        sourceHandle: edge.sourceHandle || 'default',
        targetHandle: edge.targetHandle || 'default'
      }))
    };
  }, [nodes, edges]);

  // 使用防抖来减少频繁更新
  const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  
  useEffect(() => {
    if (onFlowChange) {
      // 清除之前的定时器
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }
      
      // 设置新的定时器，延迟 300ms 执行
      debounceTimerRef.current = setTimeout(() => {
        onFlowChange(updatedFlowData);
      }, 300);
    }
    
    // 清理函数
    return () => {
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }
    };
  }, [updatedFlowData, onFlowChange]);

  const handleNodeUpdate = useCallback((nodeId: string, properties: Record<string, any>) => {
    setNodes((nds) =>
      nds.map((node) => {
        if (node.id === nodeId) {
          return {
            ...node,
            data: {
              ...(node.data || {}),
              properties: { ...(node.data?.properties || {}), ...properties }
            }
          };
        }
        return node;
      })
    );
  }, []);

  const handleNodeDelete = useCallback((nodeId: string) => {
    setNodes((nds) => nds.filter((node) => node.id !== nodeId));
    setEdges((eds) => eds.filter((edge) => edge.source !== nodeId && edge.target !== nodeId));
  }, []);

  const onConnect = useCallback(
    (params: any) => {
      setEdges((eds) => addEdge(params, eds));
    },
    [setEdges]
  );

  const onDragStart = (event: React.DragEvent, componentType: string) => {
    event.dataTransfer.setData('application/reactflow', componentType);
    event.dataTransfer.effectAllowed = 'move';
  };

  const onDragOver = useCallback((event: React.DragEvent) => {
    event.preventDefault();
    event.dataTransfer.dropEffect = 'move';
  }, []);

  const onDrop = useCallback(
    (event: React.DragEvent) => {
      event.preventDefault();

      const componentType = event.dataTransfer.getData('application/reactflow');
      if (!componentType || !reactFlowInstance) return;

      const component = availableComponents.find(c => c.type === componentType);
      if (!component) return;

      const position = reactFlowInstance.screenToFlowPosition({
        x: event.clientX,
        y: event.clientY,
      });

      const newNode: Node = {
        id: `node-${Date.now()}`,
        type: 'custom',
        position,
        data: {
          label: component.label,
          type: component.type,
          properties: {},
          onUpdate: handleNodeUpdate,
          onDelete: handleNodeDelete,
          propertiesSchema: component.propertiesSchema
        },
      };

      setNodes((nds) => nds.concat(newNode));
    },
    [reactFlowInstance, handleNodeUpdate, handleNodeDelete]
  );

  return (
    <div style={{ display: 'flex', height: '100%', gap: '16px' }}>
      {/* 左侧组件列表 */}
      <Card 
        title="组件列表" 
        style={{ width: '200px', height: 'fit-content' }}
        bodyStyle={{ padding: '8px' }}
      >
        <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
          {availableComponents.map((component) => (
            <div
              key={component.type}
              draggable
              onDragStart={(e) => onDragStart(e, component.type)}
              style={{
                padding: '12px',
                border: '1px solid #d9d9d9',
                borderRadius: '4px',
                cursor: 'grab',
                textAlign: 'center',
                background: selectedComponent === component.type ? '#e6f7ff' : '#fff',
              }}
              onMouseEnter={() => setSelectedComponent(component.type)}
              onMouseLeave={() => setSelectedComponent(null)}
            >
              <div style={{ fontSize: '20px', marginBottom: '4px' }}>{component.icon}</div>
              <div style={{ fontSize: '12px' }}>{component.label}</div>
            </div>
          ))}
        </div>
      </Card>

      {/* 中间画布 */}
      <div style={{ flex: 1, height: '600px', display: 'flex', flexDirection: 'column', gap: '16px' }}>
        <div style={{ flex: 1 }} ref={reactFlowWrapper}>
          <ReactFlow
            nodes={nodes}
            edges={edges}
            onNodesChange={onNodesChange}
            onEdgesChange={onEdgesChange}
            onConnect={onConnect}
            onInit={setReactFlowInstance}
            onDrop={onDrop}
            onDragOver={onDragOver}
            nodeTypes={nodeTypes}
            fitView
          >
            <Controls />
            <Background />
          </ReactFlow>
        </div>
        
        {/* 日志面板 */}
        {logs && logs.length > 0 && (
          <Card 
            title="执行日志" 
            size="small" 
            style={{ height: '200px' }}
            bodyStyle={{ 
              padding: '8px', 
              height: 'calc(100% - 40px)',
              overflowY: 'auto',
              background: '#001529',
              color: '#fff',
              fontFamily: 'monospace',
              fontSize: '12px'
            }}
          >
            {logs.map((log, index) => (
              <div key={index} style={{ marginBottom: '2px' }}>{log}</div>
            ))}
          </Card>
        )}
      </div>
    </div>
  );
};

export default FeatureFlowCanvas;

